package com.mapeditor.core
{
	import AS3Events.AS3EventMessage;
	import AS3Events.AS3EventRouter;
	import AS3Events.AS3EventRouterListener;
	import AS3Util.Tr;
	import com.mapeditor.graph.BackgroundGrid;
	import com.mapeditor.graph.Container;
	import com.mapeditor.graph.Menu;
	import com.mapeditor.graph.ShapeImage;
	import com.mapeditor.graph.ShapePolygon;
	import com.mapeditor.math.Vector3;
	import com.mapeditor.toolbar.MenuShape;
	import com.mapeditor.toolbar.MenuShapeItemProperties;
	import com.mapeditor.toolbar.Toolbar;
	import com.mapeditor.util.GlobalContainer;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.ContextMenuEvent;
	import flash.events.DataEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.text.TextField;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuBuiltInItems;
	import flash.ui.ContextMenuItem;
	import flash.utils.ByteArray;
	/**
	 * ...
	 * @author Osvaldo Cassaniga Junior
	 */
	public class Main extends Sprite implements AS3EventRouterListener
	{
		private var elements:Array;
		private var ctrlKey:Boolean;
		private var enabledRoomFactory:Boolean;
		private var backgroundContainer:Sprite;
		private var elementsContainer:Sprite;
		
		private var myContextMenu:ContextMenu;
		private var infos:TextField;
		private var creatorRoom:TextField;
		private var creatorPath:TextField;
		private var selectedItem:Item;
		private var showHideRoom:Boolean;
		
		private var mFileReference:FileReference;
		
		public function Main() 
		{
			showHideRoom = false;
			
			elements = new Array();
			ctrlKey = false;
			enabledRoomFactory = false;
			backgroundContainer = new Sprite();
			elementsContainer = new Sprite();
			
			var c:Container = Container.getInstance();
			addChild(c);
			
			c.addChild(backgroundContainer);
			c.addChild(elementsContainer);
			
			var menu:Menu = Menu.getInstance();
			elementsContainer.addChild(menu);
			
			var bc:BackgroundGrid = new BackgroundGrid();
			bc.draw(10000, 10000);
			backgroundContainer.addChild(bc);
			
			this.graphics.lineStyle(5, 0x0000ff);
			this.graphics.lineTo(500, 0);
			this.graphics.moveTo(0, 0);
			this.graphics.lineStyle(5, 0x00ff00);
			this.graphics.lineTo(0, 500);
			
			stage.addEventListener(KeyboardEvent.KEY_DOWN, _keyDownHandler, false, 0, true);
			stage.addEventListener(KeyboardEvent.KEY_UP, _keyUpHandler, false, 0, true);
			
			AS3EventRouter.AddEventListener("class_menu", this);
			AS3EventRouter.AddEventListener("class_item", this);
			AS3EventRouter.AddEventListener("class_load", this);
			AS3EventRouter.AddEventListener("class_room", this);
			AS3EventRouter.AddEventListener("class_toolbar", this);
			
			
			addChild(Tr.init());
			
			this._createMenu();
			
			//this.scaleX = 0.5;
			//this.scaleY = 0.5;
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN, _selectionStart);
			
			var rf:RoomFactory = RoomFactory.getInstance();
			addChild(rf);
			
			
			var s:String = "";
			s +=" Menu: Duplo clique na area de desenho.";
			s +="\n Shortcuts (Keyborad):";
			s += "\n M: Change config options";
			s += "\n 9/0: Change values Up/Down config options";
			s += "\n L: Load";
			s += "\n S: Save";
			s += "\n Setas: Scroll";
			s += "\n Ctrl + Setas: Move all items";
			
			
			infos = new TextField();
			infos.text = s;
			infos.width = 200;
			infos.height = 600;
			infos.y = 80;
			
			//addChild(infos);
			
			creatorRoom = new TextField();
			creatorRoom.text = "Room creator: ";
			creatorRoom.x = stage.stageWidth - 200;
			creatorRoom.y = 3;
			creatorRoom.height = 20;
			addChild(creatorRoom);
			
			creatorPath = new TextField();
			creatorPath.text = "Path creator: ";
			creatorPath.x = stage.stageWidth - 200;
			creatorPath.y = 18;
			creatorPath.height = 20;
			addChild(creatorPath);
			
			c.addMenu();
			
			
			var bar:Toolbar = new Toolbar();
			bar.addButtonImg("img/toolbar/save.png", 			32, 32, "btnsave");
			bar.addButtonImg("img/toolbar/load.png", 			32, 32, "btnload");
			bar.addButtonImg("img/toolbar/zoom_in.png", 		32, 32, "btnzoom_in");
			bar.addButtonImg("img/toolbar/zoom_default.png", 	32, 32, "btnzoom_default");
			bar.addButtonImg("img/toolbar/zoom_out.png", 		32, 32, "btnzoom_out");
			bar.addButtonImg("img/toolbar/left.png", 			32, 32, "btnleft");
			bar.addButtonImg("img/toolbar/right.png", 			32, 32, "btnright");
			bar.addButtonImg("img/toolbar/up.png", 				32, 32, "btnup");
			bar.addButtonImg("img/toolbar/down.png", 			32, 32, "btndown");
			
			bar.addButtonImg("img/toolbar/show_room.png", 		32, 32, "btnshow_room");
			bar.addButtonImg("img/toolbar/path.png", 			32, 32, "btnpath");
			bar.addButtonImg("img/toolbar/room_factory.png", 	32, 32, "btnroom_factory");
			bar.addButtonImg("img/toolbar/next.png", 			32, 32, "btnnext");
			bar.addButtonImg("img/toolbar/info.png", 			32, 32, "btninfo");
			
			bar.outPut();
			
			addChild(bar);
			
			
			elements[0] = new Item("center", 0, new ShapeImage("img/3d.png"));
			Item(elements[0]).x = 350;
			Item(elements[0]).y = 350;
			elementsContainer.addChild(elements[0]);
			
		}
		
		
		
		private function _selectionStart(e:MouseEvent):void {
			
			//Tr.ace("enabledRoomFactory = " + enabledRoomFactory);
			if (!enabledRoomFactory)
				return;
				
			var rf:RoomFactory = RoomFactory.getInstance();
			rf.selectionStart(e);
		}
		/***************************************************************************** 
		* ENGINE Methodo que escuta os eventos
		* @param 	eventClassName			Nome da classe de Eventos
		* @param 	event					Nome evento
		* @param 	msg						Objeto do tipo AS3EventMessage.
		* ***************************************************************************/
		public function receiveEventRouterMessage(eventClassName:String, event:String,  msg:AS3EventMessage):void {
			//trace("sou o " + nome + " e escutei a classe de evento " + eventClassName + " , evento: " + event);
			var i:uint = elements.length;
			switch (eventClassName) 
			{
				case "class_toolbar":
					switch(msg.message)
					{
						case "btnsave": 		this.save(); 		break;
						case "btnload": 		this.load(); 		break;
						case "btnzoom_in": 		this.zoomIn(); 	    break;
						case "btnzoom_default": this.zoomDefault(); break;
						case "btnzoom_out":		this.zoomOut();     break;
						case "btnleft":			this.moveLeft();    break;
						case "btnright":		this.moveRight();   break;
						case "btnup":			this.moveUp(); 		break;
						case "btndown":			this.moveDown(); 	break;
						case "btnshow_room": 
							if (showHideRoom)
								this.hideRooms();
							else
								this.showRooms();
							showHideRoom = !showHideRoom;
							break;
						case "btnpath": 		this.setEnabledPathFactory(); break;
						case "btnroom_factory": this.setEnabledRoomFactory(); break;
						case "btnnext": 		this.nextMenu(); break;
						case "btninfo": 		this.showInfo(); break;
			
					}
					break;
				case "class_menu":
					_MenuItemEvent(msg.message.name as String);
					break;
				case "class_room":
					
					var c:Container = Container.getInstance();
					
					elements[i] = new Item("" + i, Item.ROOM, new ShapePolygon(GlobalContainer.checkPosGrid(msg.message[1].x), GlobalContainer.checkPosGrid(msg.message[1].y),0xCFCFFF,0xCCCCFF,0.5));
					elements[i].x = GlobalContainer.checkPosGrid(msg.message[0].x - c.x);
					elements[i].y = GlobalContainer.checkPosGrid(msg.message[0].y - c.y);
					elementsContainer.addChild(elements[i]);
					break;
				case "class_load":
					for each (var it:Item in elements)
					{
						if(elementsContainer.contains(it))
							elementsContainer.removeChild(it);
					}
					elements = new Array();
					selectedItem = null;
					
					var load:LoadXML = LoadXML.getInstance();
					this.elements = load.elements;
					for each (var item:Item in elements)
					{
						elementsContainer.addChild(item);
						if (item.type == Item.SHIP)
							item.drawPath();
						
					}
					elementsContainer.setChildIndex(elements[0], elementsContainer.numChildren - 1);
					break;
				case "class_item":
						switch(event)
						{
							case "send_to_back":
								elementsContainer.setChildIndex(msg.message as Item, 0);
								break;
							case "delete":
								
								for (var j:uint=0, s:uint=elements.length; j < s; j++)
									if (elements[j] == msg.message)
									{
										elementsContainer.removeChild(elements[j]);
										elements.splice(j, 1);
									}
								break;
							case "item_mouse_down": break;
							case "item_mouse_down_pf_active":
								if(selectedItem == msg.message as Item)
									this.setEnabledPathFactory(false);
							//elementsContainer.setChildIndex(msg.message as Item, elementsContainer.numChildren - 1);
								
								break;
							case "item_mouse_up":
								//elementsContainer.setChildIndex(msg.message as Item, 0);
								//if (selectedItem != null)
									//selectedItem.clearPath();
								
								
								
								selectedItem = msg.message as Item;
								var menu:Menu = Menu.getInstance();
								elementsContainer.setChildIndex(menu, elementsContainer.numChildren-1);
							break;
						}
					break;
			}
		}
		private function _moveAll(vx:Number,vy:Number):void 
		{
			for (var i:uint = 0, s:uint = elements.length; i < s; i++)
			{
				elements[i].x += vx;
				elements[i].y += vy;
				for (var j:uint = 0, sp:uint = elements[i].points.length; j < sp; j++)
				{
					elements[i].points[j].x += vx;
					elements[i].points[j].y += vy;
				}
			}
		}
		
		private function changePropertie(flag:Boolean):void {
			var m:Menu = Menu.getInstance();
			m.changeValue(flag);
		}
		private function moveDown():void {
			var c:Container = Container.getInstance();
			
			if (ctrlKey)
				_moveAll(0, +10);
			else 
				c.y += 10;
			
			if (c.y > 0)
				c.y = 0;
			
		}
		private function moveRight():void {
			var c:Container = Container.getInstance();
			
			if (ctrlKey)
				_moveAll(10, 0);
			else if (!ctrlKey)
				c.x += 10;
				
			if (c.x > 0)
				c.x = 0;
		}
		private function moveUp():void {
			var c:Container = Container.getInstance();
			
			if (ctrlKey)
				_moveAll(0, -10);
			else if (!ctrlKey)
				c.y -= 10;
			
		}
		private function moveLeft():void {
			var c:Container = Container.getInstance();
			
			if (ctrlKey)
				_moveAll(-10,0);
			else 
				c.x -= 10;
		}
		
		private function zoomDefault():void {
			var c:Container = Container.getInstance();
			
			c.scaleX = 1.0;
			c.scaleY = 1.0;
		}
		private function zoomOut():void {
			var c:Container = Container.getInstance();
			
			c.scaleX -= 0.1;
			c.scaleY = c.scaleX;
		}
		private function zoomIn():void {
			var c:Container = Container.getInstance();
			
			c.scaleX += 0.1;
			c.scaleY = c.scaleX;
		}
		private function showRooms():void {
			
			for each(var i:Item in elements)
			{
				if (i.type == Item.ROOM && !elementsContainer.contains(i))
					elementsContainer.addChild(i);
			}
			
		}
		private function hideRooms():void {
			for each(var item:Item in elements)
			{
				if (item.type == Item.ROOM && elementsContainer.contains(item))
					elementsContainer.removeChild(item);
			}
			
			
		}
		private function setEnabledPathFactory(fg:Boolean=true):void {
			if (selectedItem == null || selectedItem.type != Item.SHIP)
				return;
			
			var pf:PathFactory = PathFactory.getInstance();
			if (pf.active)
			{
				removeChild(pf);
				pf.stop(stage);
				if (pf.points.length > 0)						
					selectedItem.points = pf.points;
				selectedItem.drawPath();
			}
			else if(fg)
			{
				if (!contains(pf))
					addChild(pf);
				
				selectedItem.clearPath();
				pf.graphics.clear();
				pf.start(stage,new Vector3(selectedItem.x, selectedItem.y));
				selectedItem.points = new Array;						
				
			}
			creatorPath.text = "Path creator: "+pf.active;	
		}
		private function setEnabledRoomFactory():void {
			if (!enabledRoomFactory)
			{
				elementsContainer.mouseChildren = false;
				elementsContainer.mouseEnabled = false;
			}
			else
			{
				elementsContainer.mouseChildren = true;
				elementsContainer.mouseEnabled = true;
			}
			
			enabledRoomFactory = !enabledRoomFactory;
			creatorRoom.text = "Room creator: "+enabledRoomFactory;
			
		}
		private function showInfo():void {
			
			if (this.contains(infos))
				removeChild(infos);
			else
				addChild(infos);
		}
		private function nextMenu():void {
			var menu:Menu = Menu.getInstance();
			menu.nextOption();	
		}
		private function load():void {
			
			//Tr.ace("onBrowse");
			
			mFileReference=new FileReference();
			mFileReference.addEventListener(Event.SELECT, onFileSelected);
			var swfTypeFilter:FileFilter = new FileFilter("XML","*.xml;");
			mFileReference.browse([swfTypeFilter]);
			
		}
		private function save():void {
			var xml:CreateXML = CreateXML.getInstance();
			xml.save(this.elements);
			
			
		}
							
		// This function is called after user selected a file in the file browser dialog.
		private function onFileSelected(event:Event):void
		{
			var filename:String = mFileReference.name;
			
			var t:Date = new Date();
			
			var urlRequest:URLRequest = new URLRequest("upload_file.php?nocache="+t.getMilliseconds());
			urlRequest.method = URLRequestMethod.POST;
		 
			// Optional callback to track progress of uploading
			mFileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,onUploadComplete);
			mFileReference.upload(urlRequest);
			
		}
		 
		 
		 
		private function onUploadComplete(event:Event):void
		{
			//Tr.ace("upload complete");
			// Optional callback to track progress of uploading
			mFileReference.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadComplete);			
			
			var load:LoadXML = LoadXML.getInstance();
			load.loadXML();
		}					
		
		private function _keyDownHandler(event:KeyboardEvent):void {
			if (event.ctrlKey)
				ctrlKey = true;
				
			var c:Container = Container.getInstance();
			//Tr.ace("key: " + event.keyCode);
			switch(event.keyCode) {
				case 37: this.moveLeft(); break;
				case 38: this.moveUp(); break;
				case 39: this.moveRight(); break;
				case 40: this.moveDown(); break;
				case 46: break;//delete						
				case 57: this.changePropertie(true); break; //9
				case 48: this.changePropertie(false); break;//0
			}
		}//end of method
		
		/***************************************************************************** 
		* Metodo para tratar evento de teclado apos soltar a tecla
		* @param	event		Evento do tipo KeyBoard
		* ***************************************************************************/		
		private function _keyUpHandler(event:KeyboardEvent):void {
			//app.setCtrlKey(false);
			var c:Container = Container.getInstance();
			//Tr.ace("event.keyCode= " + event.keyCode);
			switch(event.keyCode) {
				case 83: this.save(); break; //s					
				case 76: this.load(); break;//L					
				case 77: this.nextMenu(); break;//M					
				
			}
			//trace("EVENT_UP_KEY=" + event.keyCode);
			//trace("EVENT_UP_CONTROL=" + event.ctrlKey);
			
			ctrlKey = false;
			
		}//end of method
		
		
		private function _createMenu():void
		{
			this.myContextMenu= new ContextMenu();
			  
			this.myContextMenu.hideBuiltInItems();

			var defaultItems:ContextMenuBuiltInItems = this.myContextMenu.builtInItems;

			defaultItems.forwardAndBack = false;    
			defaultItems.loop = false;
			defaultItems.play = false;
			defaultItems.print = false;
			defaultItems.quality = false;
			defaultItems.rewind = false;
			defaultItems.save = false;
			defaultItems.zoom = false;
			
		}
		
		private function _MenuItemEvent(value:String):void {
			
			//Tr.ace("" + value + "->" + mouseX + "," + mouseY);
			var c:Container = Container.getInstance();
			var i:uint = elements.length;
			switch(value)
			{
				case "terrain1":
					elements[i] = new Item("Platform", Item.PLATFORM, new ShapeImage("img/terrain1.png",0,0,0.5));
					break;
					
				case "tank01":
					elements[i] = new Item("Tank01", Item.SHIP, new ShapeImage("img/tank1.png"));
					elements[i].speed = 100;
					elements[i].dist = 1000;
					elements[i].frequence = 0.5;
					break;
				case "tank02":
					elements[i] = new Item("Tank02", Item.SHIP, new ShapeImage("img/tank2.png"));
					elements[i].speed = 200;
					elements[i].dist = 600;
					elements[i].frequence = 1.0;
					break;
				case "tank03":
					elements[i] = new Item("Tank03", Item.SHIP, new ShapeImage("img/tank3.png"));
					elements[i].speed = 100;
					elements[i].dist = 1000;
					elements[i].frequence = 0.5;
					break;
				
				case "ship01":
					elements[i] = new Item("Ship01", Item.SHIP, new ShapeImage("img/ship01.png"));
					elements[i].speed = 100;
					elements[i].dist = 1000;
					elements[i].frequence = 0.5;
					break;
				case "ship02":
					elements[i] = new Item("Ship02", Item.SHIP, new ShapeImage("img/ship02.png"));							
					elements[i].speed = 200;
					elements[i].dist = 600;
					elements[i].frequence = 1.0;
					break;
				case "ship03":
					elements[i] = new Item("Ship03", Item.SHIP, new ShapeImage("img/ship03.png"));
					elements[i].speed = 100;
					elements[i].dist = 1000;
					elements[i].frequence = 0.5;
					break;
					
				case "tower01":
					elements[i] = new Item("Tower01", Item.TOWER, new ShapeImage("img/tower01.png"));
					elements[i].dist = 700;
					elements[i].life = 40;
					break
				case "tower02":
					elements[i] = new Item("Tower02", Item.TOWER, new ShapeImage("img/tower02.png"));
					elements[i].frequence = 1;
					elements[i].life = 80;					
					break;
				case "tower03":
					elements[i] = new Item("Tower03", Item.TOWER, new ShapeImage("img/tower03.png"));
					elements[i].frequence = 3;
					elements[i].life = 10;					
					break;
				case "bridge":				
					elements[i] = new Item("BridgeVertical", Item.BRIDGE, new ShapeImage("img/bridge.png", 0, 0, 0.5));
					break;
				case "bridge_rotate":
					elements[i] = new Item("BridgeHorizontal", Item.BRIDGE, new ShapeImage("img/bridge_rotate.png",0,0,0.5));
					break;	
				case "portal":
					elements[i] = new Item("Portal", Item.PORTAL, new ShapeImage("img/portal.png"));
					break;	
				case "powerup_life":
					elements[i] = new Item("Life", Item.POWERUP, new ShapeImage("img/powerup_life.png"));
					elements[i].powerup_life = 20;
					elements[i].powerup_tiro = 0;
					break;
				case "powerup_shot":
					elements[i] = new Item("Shot", Item.POWERUP, new ShapeImage("img/powerup_shot.png"));
					elements[i].powerup_tiro = 2;
					elements[i].powerup_life = 0;
					break;
				case "house_ramp":
					elements[i] = new Item("HouseRamp", Item.BUILD, new ShapeImage("img/build/house_ramp.png"));
					break;					
				case "house_corner":
					elements[i] = new Item("HouseCorner", Item.BUILD, new ShapeImage("img/build/house_corner.png"));
					break;
					
			}
			
			elements[i].x = mouseX-c.x;
			elements[i].y = mouseY-c.y;			
			elementsContainer.addChild(elements[i]);
		}
		
	}

}